using B.S.XZYData.Api.Wrter.Application.Command.Plan;
using B.S.XZYData.Domain.LJC;
using B.S.XZYData.ErrorCode;
using B.S.XZYData.Infrastructure.Interface;
using MediatR;
using Microsoft.Extensions.Logging;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System.Drawing;

namespace B.S.XZYData.Api.Wrter.Application.Handler.Plan
{
    /// <summary>
    /// 导出生产计划处理器
    /// </summary>
    public class ExportPlanHandler : IRequestHandler<ExportPlanCommand, ApiResult<byte[]>>
    {
        private readonly IBaseRepository<PlanModel> _planRepository;
        private readonly IBaseRepository<PlanItemModel> _planItemRepository;
        private readonly ILogger<ExportPlanHandler> _logger;

        public ExportPlanHandler(
            IBaseRepository<PlanModel> planRepository,
            IBaseRepository<PlanItemModel> planItemRepository,
            ILogger<ExportPlanHandler> logger)
        {
            _planRepository = planRepository;
            _planItemRepository = planItemRepository;
            _logger = logger;
        }

        public async Task<ApiResult<byte[]>> Handle(ExportPlanCommand request, CancellationToken cancellationToken)
        {
            try
            {
                // 查询数据
                List<PlanModel> plans;
                if (request.PlanIds != null && request.PlanIds.Any())
                {
                    plans = _planRepository.GetAll()
                        .Where(x => request.PlanIds.Contains(x.Id))
                        .ToList();
                }
                else
                {
                    plans = _planRepository.GetAll().ToList();
                }

                if (!plans.Any())
                {
                    return new ApiResult<byte[]>
                    {
                        Code = ApiEnum.Fail,
                        Msg = "没有找到要导出的数据"
                    };
                }

                // 查询所有计划的明细
                var planIds = plans.Select(x => x.Id).ToList();
                var planItems = _planItemRepository.GetAll()
                    .Where(x => planIds.Contains(x.PlanId))
                    .ToList();

                // 创建工作簿 (使用 XLSX 格式)
                IWorkbook workbook = new XSSFWorkbook();
                
                // 创建工作表
                ISheet worksheet = workbook.CreateSheet("生产计划");

                // 创建标题行样式
                ICellStyle headerStyle = workbook.CreateCellStyle();
                headerStyle.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.LightBlue.Index;
                headerStyle.FillPattern = FillPattern.SolidForeground;
                headerStyle.BorderTop = BorderStyle.Thin;
                headerStyle.BorderBottom = BorderStyle.Thin;
                headerStyle.BorderLeft = BorderStyle.Thin;
                headerStyle.BorderRight = BorderStyle.Thin;

                IFont headerFont = workbook.CreateFont();
                headerFont.IsBold = true;
                headerStyle.SetFont(headerFont);

                // 创建数据行样式
                ICellStyle dataStyle = workbook.CreateCellStyle();
                dataStyle.BorderTop = BorderStyle.Thin;
                dataStyle.BorderBottom = BorderStyle.Thin;
                dataStyle.BorderLeft = BorderStyle.Thin;
                dataStyle.BorderRight = BorderStyle.Thin;

                // 设置表头
                var headers = new[]
                {
                    "计划单号", "备注", "创建时间", "产品编号", "产品名称", 
                    "规格", "单位", "计划数量", "完成数量", "库位"
                };

                // 创建标题行
                IRow headerRow = worksheet.CreateRow(0);
                for (int i = 0; i < headers.Length; i++)
                {
                    ICell cell = headerRow.CreateCell(i);
                    cell.SetCellValue(headers[i]);
                    cell.CellStyle = headerStyle;
                }

                // 填充数据
                int rowIndex = 1;
                foreach (var plan in plans.OrderBy(x => x.CreateTime))
                {
                    var items = planItems.Where(x => x.PlanId == plan.Id).ToList();
                    
                    if (items.Any())
                    {
                        foreach (var item in items)
                        {
                            IRow dataRow = worksheet.CreateRow(rowIndex);
                            
                            SetCellValue(dataRow, 0, plan.Code ?? "", dataStyle);
                            SetCellValue(dataRow, 1, plan.Remark ?? "", dataStyle);
                            SetCellValue(dataRow, 2, plan.CreateTime.ToString(), dataStyle);
                            SetCellValue(dataRow, 3, item.ProductCode ?? "", dataStyle);
                            SetCellValue(dataRow, 4, item.ProductName ?? "", dataStyle);
                            SetCellValue(dataRow, 5, item.Spec ?? "", dataStyle);
                            SetCellValue(dataRow, 6, "", dataStyle);
                            SetCellValue(dataRow, 7, item.Quantity.ToString(), dataStyle);
                            SetCellValue(dataRow, 8, (item.DoneQuantity ?? 0).ToString(), dataStyle);
                            SetCellValue(dataRow, 9, "", dataStyle);

                            rowIndex++;
                        }
                    }
                    else
                    {
                        // 没有明细的计划也要显示
                        IRow dataRow = worksheet.CreateRow(rowIndex);
                        
                        SetCellValue(dataRow, 0, plan.Code ?? "", dataStyle);
                        SetCellValue(dataRow, 1, plan.Remark ?? "", dataStyle);
                        SetCellValue(dataRow, 2, plan.CreateTime.ToString(), dataStyle);
                        SetCellValue(dataRow, 3, "", dataStyle);
                        SetCellValue(dataRow, 4, "", dataStyle);
                        SetCellValue(dataRow, 5, "", dataStyle);
                        SetCellValue(dataRow, 6, "", dataStyle);
                        SetCellValue(dataRow, 7, "", dataStyle);
                        SetCellValue(dataRow, 8, "", dataStyle);
                        SetCellValue(dataRow, 9, "", dataStyle);

                        rowIndex++;
                    }
                }

                // 自动调整列宽
                for (int i = 0; i < headers.Length; i++)
                {
                    worksheet.AutoSizeColumn(i);
                    // 设置最大列宽，防止过宽
                    if (worksheet.GetColumnWidth(i) > 8000)
                    {
                        worksheet.SetColumnWidth(i, 8000);
                    }
                }

                // 将工作簿写入内存流
                using var memoryStream = new MemoryStream();
                workbook.Write(memoryStream);
                var excelBytes = memoryStream.ToArray();

                _logger.LogInformation($"成功导出生产计划 {plans.Count} 条，操作人：{request.OperateBy}");

                return new ApiResult<byte[]>
                {
                    Code = ApiEnum.Success,
                    Msg = $"成功导出 {plans.Count} 条生产计划",
                    Data = excelBytes
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"导出生产计划失败，操作人：{request.OperateBy}");
                return new ApiResult<byte[]>
                {
                    Code = ApiEnum.Fail,
                    Msg = $"导出失败：{ex.Message}"
                };
            }
        }

        /// <summary>
        /// 设置单元格值和样式的辅助方法
        /// </summary>
        private void SetCellValue(IRow row, int columnIndex, string value, ICellStyle style)
        {
            ICell cell = row.CreateCell(columnIndex);
            cell.SetCellValue(value);
            cell.CellStyle = style;
        }
    }
} 